Handle the possibility of a drop having no benefits

This commit is contained in:
DevilXD committed 2025-08-24 09:55:47 +02:00
1 parent 56a7fd4fb2
commit f990437731
1 file changed
+14 -5
+14 -5
View File
@@ -64,7 +64,7 @@ class BaseDrop:
self.id: str = data["id"] self.id: str = data["id"]
self.name: str = data["name"] self.name: str = data["name"]
self.campaign: DropsCampaign = campaign self.campaign: DropsCampaign = campaign
self.benefits: list[Benefit] = [Benefit(b) for b in data["benefitEdges"]] self.benefits: list[Benefit] = [Benefit(b) for b in (data["benefitEdges"] or [])]
self.starts_at: datetime = timestamp(data["startAt"]) self.starts_at: datetime = timestamp(data["startAt"])
self.ends_at: datetime = timestamp(data["endAt"]) self.ends_at: datetime = timestamp(data["endAt"])
self.claim_id: str | None = None self.claim_id: str | None = None
@@ -89,7 +89,7 @@ class BaseDrop:
and all(self.starts_at <= dt < self.ends_at for dt in dts) and all(self.starts_at <= dt < self.ends_at for dt in dts)
): ):
self.is_claimed = True self.is_claimed = True
self._precondition_drops: list[str] = [d["id"] for d in (data["preconditionDrops"] or [])] self.precondition_drops: list[str] = [d["id"] for d in (data["preconditionDrops"] or [])]
def __repr__(self) -> str: def __repr__(self) -> str:
if self.is_claimed: if self.is_claimed:
@@ -103,13 +103,15 @@ class BaseDrop:
@cached_property @cached_property
def preconditions_met(self) -> bool: def preconditions_met(self) -> bool:
campaign = self.campaign campaign = self.campaign
return all(campaign.timed_drops[pid].is_claimed for pid in self._precondition_drops) return all(campaign.timed_drops[pid].is_claimed for pid in self.precondition_drops)
def _base_earn_conditions(self) -> bool: def _base_earn_conditions(self) -> bool:
# define when a drop can be earned or not # define when a drop can be earned or not
return ( return (
self.preconditions_met # preconditions are met self.preconditions_met # preconditions are met
and not self.is_claimed # isn't already claimed and not self.is_claimed # isn't already claimed
# has at least one benefit, or participates in a preconditions chain
and (bool(self.benefits) or self.id in self.campaign.preconditions_chain())
) )
def _base_can_earn(self) -> bool: def _base_can_earn(self) -> bool:
@@ -247,7 +249,7 @@ class TimedDrop(BaseDrop):
return self.required_minutes + max( return self.required_minutes + max(
( (
self.campaign.timed_drops[pid].total_required_minutes self.campaign.timed_drops[pid].total_required_minutes
for pid in self._precondition_drops for pid in self.precondition_drops
), ),
default=0, default=0,
) )
@@ -257,7 +259,7 @@ class TimedDrop(BaseDrop):
return self.remaining_minutes + max( return self.remaining_minutes + max(
( (
self.campaign.timed_drops[pid].total_remaining_minutes self.campaign.timed_drops[pid].total_remaining_minutes
for pid in self._precondition_drops for pid in self.precondition_drops
), ),
default=0, default=0,
) )
@@ -413,6 +415,13 @@ class DropsCampaign:
def availability(self) -> float: def availability(self) -> float:
return min(d.availability for d in self.drops) return min(d.availability for d in self.drops)
def preconditions_chain(self) -> set[str]:
return set(
chain.from_iterable(
drop.precondition_drops for drop in self.drops if not drop.is_claimed
)
)
def _on_claim(self) -> None: def _on_claim(self) -> None:
invalidate_cache(self, "finished", "claimed_drops", "remaining_drops") invalidate_cache(self, "finished", "claimed_drops", "remaining_drops")
for drop in self.drops: for drop in self.drops: