diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 57a67384a0..53eedc4568 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2100,6 +2100,7 @@ PStruct::PStruct(FName name, PTypeBase *outer) { mDescriptiveName.Format("Struct<%s>", name.GetChars()); Size = 0; + HasNativeFields = false; } //========================================================================== @@ -2114,7 +2115,7 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArrayFlags & VARF_Native)) { - field->Type->SetDefaultValue(base, offset + field->Offset, special); + field->Type->SetDefaultValue(base, unsigned(offset + field->Offset), special); } } } @@ -2216,13 +2217,13 @@ bool PStruct::ReadFields(FSerializer &ar, void *addr) const PField *PStruct::AddField(FName name, PType *type, DWORD flags) { - PField *field = new PField(name, type); + PField *field = new PField(name, type, flags); // The new field is added to the end of this struct, alignment permitting. field->Offset = (Size + (type->Align - 1)) & ~(type->Align - 1); // Enlarge this struct to enclose the new field. - Size = field->Offset + type->Size; + Size = unsigned(field->Offset + type->Size); // This struct's alignment is the same as the largest alignment of any of // its fields. @@ -2238,6 +2239,29 @@ PField *PStruct::AddField(FName name, PType *type, DWORD flags) return field; } +//========================================================================== +// +// PStruct :: AddField +// +// Appends a new native field to the struct. Returns either the new field +// or NULL if a symbol by that name already exists. +// +//========================================================================== + +PField *PStruct::AddNativeField(FName name, PType *type, size_t address, DWORD flags, int bitvalue) +{ + PField *field = new PField(name, type, flags|VARF_Native, address, bitvalue); + + if (Symbols.AddSymbol(field) == nullptr) + { // name is already in use + delete field; + return nullptr; + } + Fields.Push(field); + HasNativeFields = true; + return field; +} + //========================================================================== // // PStruct :: PropagateMark @@ -2286,7 +2310,7 @@ PField::PField() } PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue) - : PSymbol(name), Offset(unsigned(offset)), Type(type), Flags(flags) + : PSymbol(name), Offset(offset), Type(type), Flags(flags) { BitValue = bitvalue; if (bitvalue > -1) @@ -3085,7 +3109,7 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags) { Defaults = (BYTE *)M_Realloc(Defaults, Size); memset(Defaults + oldsize, 0, Size - oldsize); - type->SetDefaultValue(Defaults, field->Offset, &SpecialInits); + type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits); } return field; } diff --git a/src/dobjtype.h b/src/dobjtype.h index 5aeefac502..db468870f6 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -574,7 +574,7 @@ class PField : public PSymbol public: PField(FName name, PType *type, DWORD flags = 0, size_t offset = 0, int bitvalue = -1); - unsigned int Offset; + size_t Offset; PType *Type; DWORD Flags; int BitValue; @@ -669,8 +669,10 @@ public: PStruct(FName name, PTypeBase *outer); TArray Fields; + bool HasNativeFields; virtual PField *AddField(FName name, PType *type, DWORD flags=0); + virtual PField *AddNativeField(FName name, PType *type, size_t address, DWORD flags = 0, int bitvalue = -1); size_t PropagateMark(); diff --git a/src/g_level.cpp b/src/g_level.cpp index 9e8448879f..5b0c46fa2b 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1848,6 +1848,65 @@ void FLevelLocals::AddScroller (int secnum) } } +//========================================================================== +// +// sets up the script-side version of FLevelLocals +// Since this is a global variable and the script compiler does +// not allow defining them, it will be fully set up here. +// +//========================================================================== + +inline int val2bit(int val) +{ + int bit = 0; + while ((val >>= 1)) bit++; + return bit; +} + +void G_InitLevelLocalsForScript() +{ + PStruct *lstruct = NewStruct("LevelLocals", nullptr); + PField *levelf = new PField("level", lstruct, VARF_Native | VARF_Static, (intptr_t)&level); + GlobalSymbols.AddSymbol(levelf); + + // This only exports a selection of fields. Not everything here is useful to the playsim. + lstruct->AddNativeField("time", TypeSInt32, myoffsetof(FLevelLocals, time), VARF_ReadOnly); + lstruct->AddNativeField("maptime", TypeSInt32, myoffsetof(FLevelLocals, maptime), VARF_ReadOnly); + lstruct->AddNativeField("totaltime", TypeSInt32, myoffsetof(FLevelLocals, totaltime), VARF_ReadOnly); + lstruct->AddNativeField("starttime", TypeSInt32, myoffsetof(FLevelLocals, starttime), VARF_ReadOnly); + lstruct->AddNativeField("partime", TypeSInt32, myoffsetof(FLevelLocals, partime), VARF_ReadOnly); + lstruct->AddNativeField("sucktime", TypeSInt32, myoffsetof(FLevelLocals, sucktime), VARF_ReadOnly); + lstruct->AddNativeField("cluster", TypeSInt32, myoffsetof(FLevelLocals, cluster), VARF_ReadOnly); + lstruct->AddNativeField("clusterflags", TypeSInt32, myoffsetof(FLevelLocals, clusterflags), VARF_ReadOnly); + lstruct->AddNativeField("levelnum", TypeSInt32, myoffsetof(FLevelLocals, levelnum), VARF_ReadOnly); + //lstruct->AddNativeField("levelname", TypeString, myoffsetof(FLevelLocals, LevelName), VARF_ReadOnly); // must use an access function to resolve string table references. + lstruct->AddNativeField("mapname", TypeString, myoffsetof(FLevelLocals, MapName), VARF_ReadOnly); + lstruct->AddNativeField("nextmap", TypeString, myoffsetof(FLevelLocals, NextMap)); + lstruct->AddNativeField("nextsecretmap", TypeString, myoffsetof(FLevelLocals, NextSecretMap)); + lstruct->AddNativeField("maptype", TypeSInt32, myoffsetof(FLevelLocals, maptype), VARF_ReadOnly); + lstruct->AddNativeField("monsterstelefrag", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_MONSTERSTELEFRAG)); + lstruct->AddNativeField("actownspecial", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_ACTOWNSPECIAL)); + lstruct->AddNativeField("sndseqtotalctrl", TypeSInt32, myoffsetof(FLevelLocals, flags), VARF_ReadOnly, val2bit(LEVEL_SNDSEQTOTALCTRL)); + lstruct->AddNativeField("allmap", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_ALLMAP)); + lstruct->AddNativeField("missilesactivateimpact", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MISSILESACTIVATEIMPACT)); + lstruct->AddNativeField("monsterfallingdamage", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_MONSTERFALLINGDAMAGE)); + lstruct->AddNativeField("checkswitchrange", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_CHECKSWITCHRANGE)); + lstruct->AddNativeField("polygrind", TypeSInt32, myoffsetof(FLevelLocals, flags2), 0, val2bit(LEVEL2_POLYGRIND)); + lstruct->AddNativeField("music", TypeString, myoffsetof(FLevelLocals, Music), VARF_ReadOnly); + lstruct->AddNativeField("musicorder", TypeSInt32, myoffsetof(FLevelLocals, musicorder), VARF_ReadOnly); + lstruct->AddNativeField("total_secrets", TypeSInt32, myoffsetof(FLevelLocals, total_secrets), VARF_ReadOnly); + lstruct->AddNativeField("found_secrets", TypeSInt32, myoffsetof(FLevelLocals, found_secrets)); + lstruct->AddNativeField("total_items", TypeSInt32, myoffsetof(FLevelLocals, total_items), VARF_ReadOnly); + lstruct->AddNativeField("found_items", TypeSInt32, myoffsetof(FLevelLocals, found_items)); + lstruct->AddNativeField("total_monsters", TypeSInt32, myoffsetof(FLevelLocals, total_monsters), VARF_ReadOnly); + lstruct->AddNativeField("killed_monsters", TypeSInt32, myoffsetof(FLevelLocals, killed_monsters)); + lstruct->AddNativeField("gravity", TypeFloat64, myoffsetof(FLevelLocals, gravity)); + lstruct->AddNativeField("aircontrol", TypeFloat64, myoffsetof(FLevelLocals, aircontrol)); + lstruct->AddNativeField("airfriction", TypeFloat64, myoffsetof(FLevelLocals, airfriction)); + lstruct->AddNativeField("airsupply", TypeSInt32, myoffsetof(FLevelLocals, airsupply)); + lstruct->AddNativeField("teamdamage", TypeFloat64, myoffsetof(FLevelLocals, teamdamage)); +} + //========================================================================== // // Lists all currently defined maps diff --git a/src/g_level.h b/src/g_level.h index 2b0de7b687..790eba3444 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -260,7 +260,7 @@ struct FOptionalMapinfoDataPtr typedef TMap FOptData; typedef TMap FMusicMap; -enum EMapType +enum EMapType : int { MAPTYPE_UNKNOWN = 0, MAPTYPE_DOOM, diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 77082f3a43..8337320081 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1790,6 +1790,13 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) } } +DEFINE_ACTION_FUNCTION(AActor, LookForPlayers) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_BOOL(allaround); + ACTION_RETURN_BOOL(P_LookForPlayers(self, allaround, nullptr)); +} + // // ACTION ROUTINES // diff --git a/src/p_map.cpp b/src/p_map.cpp index a2e83b73f4..d7bffa5895 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -444,6 +444,17 @@ bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi return true; } +DEFINE_ACTION_FUNCTION(AActor, TeleportMove) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + PARAM_BOOL(telefrag); + PARAM_BOOL_DEF(modify); + ACTION_RETURN_BOOL(P_TeleportMove(self, DVector3(x, y, z), telefrag, modify)); +} + //========================================================================== // // [RH] P_PlayerStartStomp diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index bd78fdcef4..08b6627679 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -990,6 +990,15 @@ void AActor::CopyFriendliness (AActor *other, bool changeTarget, bool resetHealt level.total_monsters += CountsAsKill(); } +DEFINE_ACTION_FUNCTION(AActor, CopyFriendliness) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT(other, AActor); + PARAM_BOOL_DEF(changetarget); + PARAM_BOOL_DEF(resethealth); + self->CopyFriendliness(other, changetarget, resethealth); + return 0; +} //============================================================================ // // AActor :: ObtainInventory @@ -6515,6 +6524,12 @@ DDropItem *AActor::GetDropItems() const return GetClass()->DropItems; } +DEFINE_ACTION_FUNCTION(AActor, GetDropItems) +{ + PARAM_SELF_PROLOGUE(AActor); + ACTION_RETURN_OBJECT(self->GetDropItems()); +} + double AActor::GetGravity() const { if (flags & MF_NOGRAVITY) return 0; diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 620d9feed7..50cd7699b1 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -5067,6 +5067,12 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global constant\n", Identifier.GetChars()); newex = FxConstant::MakeConstant(sym, ScriptPosition); } + else if (sym->IsKindOf(RUNTIME_CLASS(PField))) + { + // internally defined global variable + ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global variable\n", Identifier.GetChars()); + newex = new FxGlobalVariable(static_cast(sym), ScriptPosition); + } else { ScriptPosition.Message(MSG_ERROR, "Invalid global identifier '%s'\n", Identifier.GetChars()); @@ -5303,6 +5309,72 @@ ExpEmit FxSelf::Emit(VMFunctionBuilder *build) } +//========================================================================== +// +// +// +//========================================================================== + +FxGlobalVariable::FxGlobalVariable(PField* mem, const FScriptPosition &pos) + : FxExpression(EFX_GlobalVariable, pos) +{ + membervar = mem; + AddressRequested = false; + AddressWritable = true; // must be true unless classx tells us otherwise if requested. +} + +//========================================================================== +// +// +// +//========================================================================== + +bool FxGlobalVariable::RequestAddress(bool *writable) +{ + AddressRequested = true; + if (writable != nullptr) *writable = AddressWritable && !(membervar->Flags & VARF_ReadOnly); + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +FxExpression *FxGlobalVariable::Resolve(FCompileContext &ctx) +{ + CHECKRESOLVED(); + ValueType = membervar->Type; + return this; +} + +ExpEmit FxGlobalVariable::Emit(VMFunctionBuilder *build) +{ + ExpEmit obj(build, REGT_POINTER); + + build->Emit(OP_LKP, obj.RegNum, build->GetConstantAddress((void*)(intptr_t)membervar->Offset, ATAG_GENERIC)); + if (AddressRequested) + { + return obj; + } + + ExpEmit loc(build, membervar->Type->GetRegType(), membervar->Type->GetRegCount()); + + if (membervar->BitValue == -1) + { + int offsetreg = build->GetConstantInt(0); + build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, obj.RegNum, offsetreg); + } + else + { + build->Emit(OP_LBIT, loc.RegNum, obj.RegNum, 1 << membervar->BitValue); + } + obj.Free(build); + return loc; +} + + //========================================================================== // // @@ -5377,11 +5449,21 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx) classx = nullptr; return x; } + else if (classx->ExprType == EFX_GlobalVariable) + { + auto parentfield = static_cast(classx)->membervar; + auto newfield = new PField(membervar->SymbolName, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset, membervar->BitValue); + static_cast(classx)->membervar = newfield; + classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. + auto x = classx->Resolve(ctx); + classx = nullptr; + return x; + } else if (classx->ExprType == EFX_LocalVariable && classx->IsVector()) // vectors are a special case because they are held in registers { // since this is a vector, all potential things that may get here are single float or an xy-vector. auto locvar = static_cast(classx); - locvar->RegOffset = membervar->Offset / 8; + locvar->RegOffset = int(membervar->Offset / 8); locvar->ValueType = membervar->Type; classx = nullptr; delete this; @@ -5816,13 +5898,15 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) case NAME_Name: case NAME_Color: case NAME_Sound: + case NAME_State: if (CheckArgSize(MethodName, ArgList, 1, 1, ScriptPosition)) { PType *type = MethodName == NAME_Int ? TypeSInt32 : MethodName == NAME_uInt ? TypeUInt32 : MethodName == NAME_Double ? TypeFloat64 : MethodName == NAME_Name ? TypeName : - MethodName == NAME_Color ? TypeColor : (PType*)TypeSound; + MethodName == NAME_Color ? TypeColor : + MethodName == NAME_State? TypeState :(PType*)TypeSound; func = new FxTypeCast((*ArgList)[0], type, true, true); (*ArgList)[0] = nullptr; @@ -6615,14 +6699,19 @@ ExpEmit FxVectorBuiltin::Emit(VMFunctionBuilder *build) FxExpression *FxSequence::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); + bool fail = false; for (unsigned i = 0; i < Expressions.Size(); ++i) { if (nullptr == (Expressions[i] = Expressions[i]->Resolve(ctx))) { - delete this; - return nullptr; + fail = true; } } + if (fail) + { + delete this; + return nullptr; + } return this; } diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h index ee792e5bfd..b118b8d5d4 100644 --- a/src/scripting/codegeneration/codegen.h +++ b/src/scripting/codegeneration/codegen.h @@ -269,6 +269,7 @@ enum EFxType EFX_VectorBuiltin, EFX_TypeCheck, EFX_DynamicCast, + EFX_GlobalVariable, EFX_COUNT }; @@ -1136,6 +1137,25 @@ public: }; +//========================================================================== +// +// FxGlobalVariaböe +// +//========================================================================== + +class FxGlobalVariable : public FxExpression +{ +public: + PField *membervar; + bool AddressRequested; + bool AddressWritable; + + FxGlobalVariable(PField*, const FScriptPosition&); + FxExpression *Resolve(FCompileContext&); + bool RequestAddress(bool *writable); + ExpEmit Emit(VMFunctionBuilder *build); +}; + //========================================================================== // // FxClassMember diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 8c42e8987d..38bf2bcf6c 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -215,6 +215,7 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id, //========================================================================== void ParseScripts(); void ParseAllDecorate(); +void G_InitLevelLocalsForScript(); void LoadActors () { @@ -223,6 +224,7 @@ void LoadActors () timer.Reset(); timer.Clock(); FScriptPosition::ResetErrorCounter(); + G_InitLevelLocalsForScript(); InitThingdef(); FScriptPosition::StrictErrors = true; ParseScripts(); diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index b0edcb167f..4d18a083bc 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -673,10 +673,16 @@ void InitThingdef() qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp); } + PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor)); + + PStruct *sstruct = NewStruct("Sector", nullptr); + auto sptr = NewPointer(sstruct); + sstruct->AddNativeField("soundtarget", TypeActor, myoffsetof(sector_t, SoundTarget)); + // Define some member variables we feel like exposing to the user PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols; PType *array5 = NewArray(TypeSInt32, 5); - PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor)); + symt.AddSymbol(new PField("sector", sptr, VARF_Native, myoffsetof(AActor, Sector))); symt.AddSymbol(new PField(NAME_Alpha, TypeFloat64, VARF_Native, myoffsetof(AActor, Alpha))); symt.AddSymbol(new PField(NAME_Angle, TypeFloat64, VARF_Native, myoffsetof(AActor, Angles.Yaw))); symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor, args))); @@ -725,12 +731,14 @@ void InitThingdef() symt.AddSymbol(new PField("RipperLevel", TypeSInt32, VARF_Native, myoffsetof(AActor, RipperLevel))); symt.AddSymbol(new PField("RipLevelMin", TypeSInt32, VARF_Native, myoffsetof(AActor, RipLevelMin))); symt.AddSymbol(new PField("RipLevelMax", TypeSInt32, VARF_Native, myoffsetof(AActor, RipLevelMax))); + symt.AddSymbol(new PField("special2", TypeSInt32, VARF_Native, myoffsetof(AActor, special2))); symt.AddSymbol(new PField(NAME_VisibleStartAngle, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleStartAngle))); symt.AddSymbol(new PField(NAME_VisibleStartPitch, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleStartPitch))); symt.AddSymbol(new PField(NAME_VisibleEndAngle, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleEndAngle))); symt.AddSymbol(new PField(NAME_VisibleEndPitch, TypeFloat64, VARF_Native, myoffsetof(AActor, VisibleEndPitch))); symt.AddSymbol(new PField("AttackSound", TypeSound, VARF_Native, myoffsetof(AActor, AttackSound))); symt.AddSymbol(new PField("DeathSound", TypeSound, VARF_Native, myoffsetof(AActor, DeathSound))); + symt.AddSymbol(new PField("SeeSound", TypeSound, VARF_Native, myoffsetof(AActor, SeeSound))); symt.AddSymbol(new PField("Pos", TypeVector3, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, __Pos))); symt.AddSymbol(new PField("Vel", TypeVector3, VARF_Native, myoffsetof(AActor, Vel))); symt.AddSymbol(new PField("Scale", TypeVector2, VARF_Native, myoffsetof(AActor, Scale))); @@ -761,8 +769,11 @@ void InitThingdef() PSymbolTable &symt2 = RUNTIME_CLASS(DDropItem)->Symbols; PType *TypeDropItem = NewPointer(RUNTIME_CLASS(DDropItem)); symt2.AddSymbol(new PField("Next", TypeDropItem, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Next))); - symt2.AddSymbol(new PField("ItemName", TypeName, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Name))); + symt2.AddSymbol(new PField("Name", TypeName, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Name))); symt2.AddSymbol(new PField("Probability", TypeSInt32, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Probability))); - symt2.AddSymbol(new PField("Amount", TypeSInt32, VARF_Native | VARF_ReadOnly, myoffsetof(DDropItem, Amount))); + symt2.AddSymbol(new PField("Amount", TypeSInt32, VARF_Native, myoffsetof(DDropItem, Amount))); + + PSymbolTable &symt3 = RUNTIME_CLASS(DObject)->Symbols; + symt3.AddSymbol(new PField("bDestroyed", TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(DObject, ObjectFlags), 5/*OF_EuthanizeMe*/)); } diff --git a/src/scripting/vm/vmbuilder.h b/src/scripting/vm/vmbuilder.h index 9a97c216d2..c94d85f3cc 100644 --- a/src/scripting/vm/vmbuilder.h +++ b/src/scripting/vm/vmbuilder.h @@ -30,6 +30,8 @@ public: // Returns the constant register holding the value. int GetConstantInt(int val); + int GetConstantInt(size_t val) { return GetConstantInt(int(val)); } + int GetConstantInt(unsigned val) { return GetConstantInt(int(val)); } int GetConstantFloat(double val); int GetConstantAddress(void *ptr, VM_ATAG tag); int GetConstantString(FString str); diff --git a/src/scripting/vm/vmdisasm.cpp b/src/scripting/vm/vmdisasm.cpp index ea199612c4..239a0dc51d 100644 --- a/src/scripting/vm/vmdisasm.cpp +++ b/src/scripting/vm/vmdisasm.cpp @@ -199,7 +199,7 @@ static int printf_wrapper(FILE *f, const char *fmt, ...) void VMDumpConstants(FILE *out, const VMScriptFunction *func) { - char tmp[21]; + char tmp[30]; int i, j, k, kk; if (func->KonstD != NULL && func->NumKonstD != 0) @@ -239,7 +239,7 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func) for (j = 0, k = i; j < 4 && k < func->NumKonstA; j++, k += kk) { mysnprintf(tmp, countof(tmp), "%3d. %p:%d", k, func->KonstA[k].v, func->KonstATags()[k]); - printf_wrapper(out, "%-20s", tmp); + printf_wrapper(out, "%-22s", tmp); } printf_wrapper(out, "\n"); } diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 0b3c4d40b6..091fba4b53 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -77,6 +77,10 @@ class Actor : Thinker native native void VelFromAngle(float speed = 0, float angle = 0); native bool isFriend(Actor other); native void AdjustFloorClip(); + native DropItem GetDropItems(); + native void CopyFriendliness (Actor other, bool changeTarget, bool resetHealth = true); + native bool LookForPlayers(bool allaround); + native bool TeleportMove(Vector3 pos, bool telefrag, bool modifyactor = true); // DECORATE compatible functions native bool CheckClass(class checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false); diff --git a/wadsrc/static/zscript/doom/bossbrain.txt b/wadsrc/static/zscript/doom/bossbrain.txt index 641263eccb..cb30e886bd 100644 --- a/wadsrc/static/zscript/doom/bossbrain.txt +++ b/wadsrc/static/zscript/doom/bossbrain.txt @@ -280,13 +280,12 @@ extend class Actor } */ - /* private void SpawnFly(class spawntype, sound snd) { - AActor newmobj; - AActor fog; - AActor eye = master; // The eye is the spawnshot's master, not the target! - AActor targ = target; // Unlike other projectiles, the target is the intended destination. + Actor newmobj; + Actor fog; + Actor eye = master; // The eye is the spawnshot's master, not the target! + Actor targ = target; // Unlike other projectiles, the target is the intended destination. int r; // [GZ] Should be more viable than a countdown... @@ -307,7 +306,7 @@ extend class Actor if (fog) A_PlaySound(snd, CHAN_BODY); } - class SpawnName; + class SpawnName = null; DropItem di; // di will be our drop item list iterator DropItem drop; // while drop stays as the reference point. @@ -334,7 +333,7 @@ extend class Actor } } di = drop; - n = randon[pr_spawnfly](0, n); + n = random[pr_spawnfly](0, n); while (n >= 0) { if (di.Name != 'none') @@ -385,11 +384,11 @@ extend class Actor // (if the player has made noise). newmobj.LastHeard = newmobj.Sector.SoundTarget; - if (newmobj.SeeState != null && newmobj.LookForPlayers (true, null)) + if (newmobj.SeeState != null && newmobj.LookForPlayers (true)) { newmobj.SetState (newmobj.SeeState); } - if (!(newmobj.ObjectFlags & OF_EuthanizeMe)) + if (!newmobj.bDestroyed) { // telefrag anything in this spot newmobj.TeleportMove (newmobj.pos, true); @@ -401,13 +400,8 @@ extend class Actor // remove self (i.e., cube). Destroy (); } - */ - - native - void A_SpawnFly(class spawntype = null) // needs special treatment for default - ; - /* + void A_SpawnFly(class spawntype = null) { sound snd; if (spawntype != null) @@ -419,18 +413,13 @@ extend class Actor spawntype = "SpawnFire"; snd = "brain/spawn"; } - SpawnFly(self, spawntype, snd); + SpawnFly(spawntype, snd); } - */ - - native - void A_SpawnSound() - ; - /* + + void A_SpawnSound() { // travelling cube sound A_PlaySound("brain/cube", CHAN_BODY); SpawnFly("SpawnFire", "brain/spawn"); } - */ }