From 44d51a6de9e5bd39dcf0c3f4183dea689da03c65 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 24 Nov 2018 19:03:33 +0100 Subject: [PATCH] - scriptified GetDefaultInventory. --- src/p_user.cpp | 80 +--------------------- wadsrc/static/zscript/shared/player.txt | 91 +++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 77 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index bcc4a4ef90..e70543a8bb 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1344,84 +1344,10 @@ void APlayerPawn::PlayAttacking2 () void APlayerPawn::GiveDefaultInventory () { - if (player == NULL) return; - - // HexenArmor must always be the first item in the inventory because - // it provides player class based protection that should not affect - // any other protection item. - auto myclass = GetClass(); - GiveInventoryType(PClass::FindActor(NAME_HexenArmor)); - auto harmor = FindInventory(NAME_HexenArmor); - - double *Slots = (double*)harmor->ScriptVar(NAME_Slots, nullptr); - double *SlotsIncrement = (double*)harmor->ScriptVar(NAME_SlotsIncrement, nullptr); - Slots[4] = HexenArmor[0]; - for (int i = 0; i < 4; ++i) + IFVIRTUAL(APlayerPawn, GiveDefaultInventory) { - SlotsIncrement[i] = HexenArmor[i + 1]; - } - - // BasicArmor must come right after that. It should not affect any - // other protection item as well but needs to process the damage - // before the HexenArmor does. - auto barmor = (AInventory*)Spawn(NAME_BasicArmor); - barmor->BecomeItem (); - AddInventory (barmor); - - // Now add the items from the DECORATE definition - auto di = GetDropItems(); - - while (di) - { - PClassActor *ti = PClass::FindActor (di->Name); - if (ti) - { - if (!ti->IsDescendantOf(RUNTIME_CLASS(AInventory))) - { - Printf(TEXTCOLOR_ORANGE "%s is not an inventory item and cannot be given to a player as start item.\n", ti->TypeName.GetChars()); - } - else - { - AInventory *item = FindInventory(ti); - if (item != NULL) - { - item->Amount = clamp( - item->Amount + (di->Amount ? di->Amount : ((AInventory *)item->GetDefault())->Amount), - 0, item->MaxAmount); - } - else - { - item = static_cast(Spawn(ti)); - item->ItemFlags |= IF_IGNORESKILL; // no skill multiplicators here - item->Amount = di->Amount; - if (item->IsKindOf(NAME_Weapon)) - { - // To allow better control any weapon is emptied of - // ammo before being given to the player. - static_cast(item)->AmmoGive1 = - static_cast(item)->AmmoGive2 = 0; - } - AActor *check; - if (!item->CallTryPickup(this, &check)) - { - if (check != this) - { - // Player was morphed. This is illegal at game start. - // This problem is only detectable when it's too late to do something about it... - I_Error("Cannot give morph items when starting a game"); - } - item->Destroy(); - item = NULL; - } - } - if (item != NULL && item->IsKindOf(NAME_Weapon) && - static_cast(item)->CheckAmmo(AWeapon::EitherFire, false)) - { - player->ReadyWeapon = player->PendingWeapon = static_cast (item); - } - } - } - di = di->Next; + VMValue params[1] = { (DObject*)this }; + VMCall(func, params, 1, nullptr, 0); } } diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 92c41ea6a1..72cee7276c 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -1425,6 +1425,97 @@ class PlayerPawn : Actor native return best; } + //=========================================================================== + // + // APlayerPawn :: GiveDefaultInventory + // + //=========================================================================== + + virtual void GiveDefaultInventory () + { + let player = self.player; + if (player == NULL) return; + + // HexenArmor must always be the first item in the inventory because + // it provides player class based protection that should not affect + // any other protection item. + let myclass = GetClass(); + GiveInventoryType('HexenArmor'); + let harmor = HexenArmor(FindInventory('HexenArmor')); + + harmor.Slots[4] = self.HexenArmor[0]; + for (int i = 0; i < 4; ++i) + { + harmor.SlotsIncrement[i] = self.HexenArmor[i + 1]; + } + + // BasicArmor must come right after that. It should not affect any + // other protection item as well but needs to process the damage + // before the HexenArmor does. + let barmor = BasicArmor(Spawn('BasicArmor')); + barmor.BecomeItem (); + AddInventory (barmor); + + // Now add the items from the DECORATE definition + let di = GetDropItems(); + + while (di) + { + Class ti = di.Name; + if (ti) + { + let tinv = (class)(ti); + if (!tinv) + { + Console.Printf(TEXTCOLOR_ORANGE .. "%s is not an inventory item and cannot be given to a player as start item.\n", di.Name); + } + else + { + let item = FindInventory(tinv); + if (item != NULL) + { + item.Amount = clamp( + item.Amount + (di.Amount ? di.Amount : item.default.Amount), 0, item.MaxAmount); + } + else + { + item = Inventory(Spawn(ti)); + item.bIgnoreSkill = true; // no skill multipliers here + item.Amount = di.Amount; + let weap = Weapon(item); + if (weap) + { + // To allow better control any weapon is emptied of + // ammo before being given to the player. + weap.AmmoGive1 = weap.AmmoGive2 = 0; + } + bool res; + Actor check; + [res, check] = item.CallTryPickup(self); + if (check != self) + { + // Player was morphed. This is illegal at game start. + // This problem is only detectable when it's too late to do something about it... + ThrowAbortException("Cannot give morph item '%s' when starting a game!", di.Name); + } + else if (!res) + { + item.Destroy(); + item = NULL; + } + } + let weap = Weapon(item); + if (weap != NULL && weap.CheckAmmo(Weapon.EitherFire, false)) + { + player.ReadyWeapon = player.PendingWeapon = weap; + } + } + } + di = di.Next; + } + } + + //---------------------------------------------------------------------------- // //