mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-13 07:57:51 +00:00
- scriptified the AutoUseHealth feature.
This again is a piece of code that reads and even writes to inventory items' properties, so better have it on the script side.
This commit is contained in:
parent
3182569fb8
commit
2e383073e8
2 changed files with 150 additions and 115 deletions
|
@ -757,89 +757,14 @@ void AActor::CallDie(AActor *source, AActor *inflictor, int dmgflags, FName Mean
|
||||||
// PROC P_AutoUseHealth
|
// PROC P_AutoUseHealth
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
static int CountHealth(TArray<AInventory *> &Items)
|
|
||||||
{
|
|
||||||
int counted = 0;
|
|
||||||
for(unsigned i = 0; i < Items.Size(); i++)
|
|
||||||
{
|
|
||||||
counted += Items[i]->Amount * Items[i]->health;
|
|
||||||
}
|
|
||||||
return counted;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int UseHealthItems(TArray<AInventory *> &Items, int &saveHealth)
|
|
||||||
{
|
|
||||||
int saved = 0;
|
|
||||||
|
|
||||||
while (Items.Size() > 0 && saveHealth > 0)
|
|
||||||
{
|
|
||||||
int maxhealth = 0;
|
|
||||||
int index = -1;
|
|
||||||
|
|
||||||
// Find the largest item in the list
|
|
||||||
for(unsigned i = 0; i < Items.Size(); i++)
|
|
||||||
{
|
|
||||||
if (Items[i]->health > maxhealth)
|
|
||||||
{
|
|
||||||
index = i;
|
|
||||||
maxhealth = Items[i]->health;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now apply the health items, using the same logic as Heretic and Hexen.
|
|
||||||
int count = (saveHealth + maxhealth-1) / maxhealth;
|
|
||||||
for(int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
saved += maxhealth;
|
|
||||||
saveHealth -= maxhealth;
|
|
||||||
if (--Items[index]->Amount == 0)
|
|
||||||
{
|
|
||||||
DepleteOrDestroy (Items[index]);
|
|
||||||
Items.Delete(index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return saved;
|
|
||||||
}
|
|
||||||
|
|
||||||
void P_AutoUseHealth(player_t *player, int saveHealth)
|
void P_AutoUseHealth(player_t *player, int saveHealth)
|
||||||
{
|
{
|
||||||
TArray<AInventory *> NormalHealthItems;
|
IFVM(PlayerPawn, AutoUseHealth)
|
||||||
TArray<AInventory *> LargeHealthItems;
|
|
||||||
|
|
||||||
auto hptype = PClass::FindActor(NAME_HealthPickup);
|
|
||||||
for(AInventory *inv = player->mo->Inventory; inv != NULL; inv = inv->Inventory)
|
|
||||||
{
|
{
|
||||||
if (inv->Amount > 0 && inv->IsKindOf(hptype))
|
VMValue params[] = { player->mo, saveHealth };
|
||||||
{
|
VMCall(func, params, 2, nullptr, 0);
|
||||||
int mode = inv->IntVar(NAME_autousemode);
|
|
||||||
|
|
||||||
if (mode == 1) NormalHealthItems.Push(inv);
|
|
||||||
else if (mode == 2) LargeHealthItems.Push(inv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int normalhealth = CountHealth(NormalHealthItems);
|
|
||||||
int largehealth = CountHealth(LargeHealthItems);
|
|
||||||
|
|
||||||
bool skilluse = !!G_SkillProperty(SKILLP_AutoUseHealth);
|
|
||||||
|
|
||||||
if (skilluse && normalhealth >= saveHealth)
|
|
||||||
{ // Use quartz flasks
|
|
||||||
player->health += UseHealthItems(NormalHealthItems, saveHealth);
|
|
||||||
}
|
|
||||||
else if (largehealth >= saveHealth)
|
|
||||||
{
|
|
||||||
// Use mystic urns
|
|
||||||
player->health += UseHealthItems(LargeHealthItems, saveHealth);
|
|
||||||
}
|
|
||||||
else if (skilluse && normalhealth + largehealth >= saveHealth)
|
|
||||||
{ // Use mystic urns and quartz flasks
|
|
||||||
player->health += UseHealthItems(NormalHealthItems, saveHealth);
|
|
||||||
if (saveHealth > 0) player->health += UseHealthItems(LargeHealthItems, saveHealth);
|
|
||||||
}
|
|
||||||
player->mo->health = player->health;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -851,44 +776,10 @@ CVAR(Bool, sv_disableautohealth, false, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||||
|
|
||||||
void P_AutoUseStrifeHealth (player_t *player)
|
void P_AutoUseStrifeHealth (player_t *player)
|
||||||
{
|
{
|
||||||
TArray<AInventory *> Items;
|
IFVM(PlayerPawn, AutoUseStrifeHealth)
|
||||||
|
|
||||||
auto hptype = PClass::FindActor(NAME_HealthPickup);
|
|
||||||
for(AInventory *inv = player->mo->Inventory; inv != NULL; inv = inv->Inventory)
|
|
||||||
{
|
{
|
||||||
if (inv->Amount > 0 && inv->IsKindOf(hptype))
|
VMValue params[] = { player->mo };
|
||||||
{
|
VMCall(func, params, 1, nullptr, 0);
|
||||||
int mode = inv->IntVar(NAME_autousemode);
|
|
||||||
if (mode == 3) Items.Push(inv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sv_disableautohealth)
|
|
||||||
{
|
|
||||||
while (Items.Size() > 0)
|
|
||||||
{
|
|
||||||
int maxhealth = 0;
|
|
||||||
int index = -1;
|
|
||||||
|
|
||||||
// Find the largest item in the list
|
|
||||||
for(unsigned i = 0; i < Items.Size(); i++)
|
|
||||||
{
|
|
||||||
if (Items[i]->health > maxhealth)
|
|
||||||
{
|
|
||||||
index = i;
|
|
||||||
maxhealth = Items[i]->Amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (player->health < 50)
|
|
||||||
{
|
|
||||||
if (!player->mo->UseInventory (Items[index]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (player->health >= 50) return;
|
|
||||||
// Using all of this item was not enough so delete it and restart with the next best one
|
|
||||||
Items.Delete(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,56 @@
|
||||||
|
|
||||||
|
struct AutoUseHealthInfo play
|
||||||
|
{
|
||||||
|
Array<Inventory> collectedItems[2];
|
||||||
|
int collectedHealth[2];
|
||||||
|
|
||||||
|
void AddItemToList(Inventory item, int list)
|
||||||
|
{
|
||||||
|
collectedItems[list].Push(item);
|
||||||
|
collectedHealth[list] += Item.Amount * Item.health;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UseHealthItems(int list, in out int saveHealth)
|
||||||
|
{
|
||||||
|
int saved = 0;
|
||||||
|
|
||||||
|
while (collectedItems[list].Size() > 0 && saveHealth > 0)
|
||||||
|
{
|
||||||
|
int maxhealth = 0;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
// Find the largest item in the list
|
||||||
|
for(int i = 0; i < collectedItems[list].Size(); i++)
|
||||||
|
{
|
||||||
|
// Workaround for a deficiency in the expression resolver.
|
||||||
|
let item = list == 0? collectedItems[0][i] : collectedItems[1][i];
|
||||||
|
if (Item.health > maxhealth)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
maxhealth = Item.health;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now apply the health items, using the same logic as Heretic and Hexen.
|
||||||
|
int count = (saveHealth + maxhealth-1) / maxhealth;
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
saved += maxhealth;
|
||||||
|
saveHealth -= maxhealth;
|
||||||
|
let item = list == 0? collectedItems[0][index] : collectedItems[1][index];
|
||||||
|
if (--item.Amount == 0)
|
||||||
|
{
|
||||||
|
item.DepleteOrDestroy ();
|
||||||
|
collectedItems[list].Delete(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
extend class PlayerPawn
|
extend class PlayerPawn
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -176,4 +229,95 @@ extend class PlayerPawn
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// PROC P_AutoUseHealth
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void AutoUseHealth(int saveHealth)
|
||||||
|
{
|
||||||
|
AutoUseHealthInfo collector;
|
||||||
|
|
||||||
|
for(Inventory inv = self.Inv; inv != NULL; inv = inv.Inv)
|
||||||
|
{
|
||||||
|
let hp = HealthPickup(inv);
|
||||||
|
if (hp && hp.Amount > 0)
|
||||||
|
{
|
||||||
|
int mode = hp.autousemode;
|
||||||
|
if (mode == 1 || mode == 2) collector.AddItemToList(inv, mode-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool skilluse = !!G_SkillPropertyInt(SKILLP_AutoUseHealth);
|
||||||
|
|
||||||
|
if (skilluse && collector.collectedHealth[0] >= saveHealth)
|
||||||
|
{
|
||||||
|
// Use quartz flasks
|
||||||
|
player.health += collector.UseHealthItems(0, saveHealth);
|
||||||
|
}
|
||||||
|
else if (collector.collectedHealth[1] >= saveHealth)
|
||||||
|
{
|
||||||
|
// Use mystic urns
|
||||||
|
player.health += collector.UseHealthItems(1, saveHealth);
|
||||||
|
}
|
||||||
|
else if (skilluse && collector.collectedHealth[0] + collector.collectedHealth[1] >= saveHealth)
|
||||||
|
{
|
||||||
|
// Use mystic urns and quartz flasks
|
||||||
|
player.health += collector.UseHealthItems(0, saveHealth);
|
||||||
|
if (saveHealth > 0) player.health += collector.UseHealthItems(1, saveHealth);
|
||||||
|
}
|
||||||
|
health = player.health;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// P_AutoUseStrifeHealth
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void AutoUseStrifeHealth ()
|
||||||
|
{
|
||||||
|
Array<Inventory> Items;
|
||||||
|
|
||||||
|
for(Inventory inv = self.Inv; inv != NULL; inv = inv.Inv)
|
||||||
|
{
|
||||||
|
let hp = HealthPickup(inv);
|
||||||
|
if (hp && hp.Amount > 0)
|
||||||
|
{
|
||||||
|
if (hp.autousemode == 3) Items.Push(inv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sv_disableautohealth)
|
||||||
|
{
|
||||||
|
while (Items.Size() > 0)
|
||||||
|
{
|
||||||
|
int maxhealth = 0;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
// Find the largest item in the list
|
||||||
|
for(int i = 0; i < Items.Size(); i++)
|
||||||
|
{
|
||||||
|
if (Items[i].health > maxhealth)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
maxhealth = Items[i].Amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (player.health < 50)
|
||||||
|
{
|
||||||
|
if (!UseInventory (Items[index]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (player.health >= 50) return;
|
||||||
|
// Using all of this item was not enough so delete it and restart with the next best one
|
||||||
|
Items.Delete(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue