def approve(request, membership, application_id): if not membership.hasPrivilege(AM_ACCEPT): return redirect('/register/login/') try: app = AllianceApplication.objects.get(id=int(application_id)) except ObjectDoesNotExist: return redirect('/register/login') note(request, LA_ACCEPTED_APPLICATION_TO_ALLIANCE, name=membership.alliance.name, shname=membership.alliance.shname, aid=membership.alliance.id, accid=app.applicant.id, playername=app.applicant.empire, message=app.message) AllianceMembership(None, app.applicant.id, app.alliance.id, 0, u'Nowy').save() alliance = membership.alliance alliance.members += 1 alliance.save() acceptAlliance(alliance, app.applicant) app.delete() return redirect('/alliance/accept/list/')
def order(request): '''Starts a technology research. When: Resources met Not researching any other technology worldwide Requirements met''' mum = getCurrentMother(request) costs = getCosts(mum.owner.technology, getRace(request), int(request.GET['what'])) if costs[0] > getResourceIndex(request).stateUpdate(): return HttpResponse('COSTS') if int(request.GET['what']) == 12: # supercomputer if getAccount(request).getPendingResearchesCount() > 0: return HttpResponse('QUEUE') else: if getAccount(request).getPendingResearchesCount() > mum.owner.technology.o_12: return HttpResponse('QUEUE') if not getRequirements(mum.owner.technology, getRace(request), int(request.GET['what'])).validate(mum): return HttpResponse('REQUIREMENTS') if not canAdvance(mum.owner.technology, getRace(request), int(request.GET['what'])): return HttpResponse('ADVANCE') note(request, LM_RESEARCH_ORDERED, mid=mum.id, what=int(request.GET['what']), levelfrom=mum.owner.technology.__dict__['o_'+request.GET['what']]) orderResearch(mum, int(request.GET['what']), costs) return HttpResponse('OK')
def order(request): '''Starts building land army units When: Resources met Requirements met''' mum = getCurrentMother(request) # Python will HTTP 500 on invalid GET data costs = getCosts(mum, getRace(request), int(request.GET['what'])) if not (int(request.GET['what']) in range(0,MGID+1)): return HttpResponse('WHATINVALID') if int(request.GET['amount']) < 1: return HttpResponse('INVALIDAMOUNT') if costs[0]*int(request.GET['amount']) > getResourceIndex(request).stateUpdate(): return HttpResponse('COSTS') if not getRequirements(mum, getRace(request), int(request.GET['what'])): return HttpResponse('REQUIREMENTS') note(request, LM_LANDARMY_TRAINING, mid=mum.id, what=int(request.GET['what']), amount=int(request.GET['amount'])) orderProduce(mum, getRace(request), int(request.GET['what']), int(request.GET['amount'])) return HttpResponse('OK')
def order(request, pp): mum = getCurrentMother(request) slot = int(request.GET['slot']) otype, olvl = pp.getPair(slot) if otype == 0: return HttpResponse('ZEROSLOT') # Cannot upgrade something that doesnt exist costs = getCosts(pp, getRace(request), olvl, otype) if pp.owner != getAccount(request): return HttpResponse('ACCOUNT') if costs[0] > getResourceIndex(request).stateUpdate(): return HttpResponse('COSTS') if pp.getPendingBuildingsCount() > 0: return HttpResponse('QUEUE') note(request, LP_BUILD_ORDERED, pid=pp.province.id, slot=slot, what=otype, levelfrom=olvl) orderBuild(pp, mum, otype, slot, costs) return HttpResponse('OK')
def process(request, membership, target_membership_id): try: tm = AllianceMembership.objects.get(id=int(target_membership_id)) except: return HttpResponse('INVALIDMEMBERSHIP') if membership.alliance.leader.id != getAccountId(request): return HttpResponse('YOURENOTLEADER') if tm.alliance != membership.alliance: return HttpResponse('WRONGALLIANCE') if tm.account == membership.alliance.leader: return HttpResponse('TARGETISLEADER') makeLeader(membership.alliance, tm.account) note(request, LA_MADE_LEADER, name=membership.alliance.name, shname=membership.alliance.shname, aid=membership.alliance.id, oldleader=membership.account.id, newleader=tm.account.id) tm.privileges = 255 tm.save() all = membership.alliance all.leader = tm.account all.save() return HttpResponse('OK')
def process(request, membership): if (getAccount(request) == membership.alliance.leader): return HttpResponse('LEADERCANTLEAVE') else: note(request, LA_LEAVE_ALLIANCE, name=membership.alliance.name, shname=membership.alliance.shname, aid=membership.alliance.id, accid=getAccountId(request)) membership.alliance.members -= 1 membership.alliance.save() bootFromAlliance(membership.alliance, getAccount(request)) membership.delete() return HttpResponse('OK')
def process(request): '''Checks whether the name is valid, and if possible, changes it''' mum = getCurrentMother(request) if request.GET['name'].strip() in ('', u''): return HttpResponse('') note(request, LM_NAMECHANGE, mid=mum.id, old=mum.name, new=request.GET['name']) mum.name = request.GET['name'] mum.save() return HttpResponse(mum.name)
def process(request, membership): if not (getAccount(request) == membership.alliance.leader): return HttpResponse('NOT LEADER') alliance = membership.alliance note(request, LA_DISBAND_ALLIANCE, aid=alliance.id, name=alliance.name, shname=alliance.shname) AllianceApplication.objects.filter(alliance=alliance).delete() for ams in AllianceMembership.objects.filter(alliance=membership.alliance): bootFromAlliance(alliance, ams.account) ams.delete() destroyAlliance(alliance) membership.alliance.delete() return HttpResponse('OK')
def decline(request, membership, application_id): if not membership.hasPrivilege(AM_ACCEPT): return redirect('/register/login/') try: app = AllianceApplication.objects.get(id=int(application_id)) except ObjectDoesNotExist: return redirect('/register/login') note(request, LA_DECLINED_APPLICATION_TO_ALLIANCE, name=membership.alliance.name, shname=membership.alliance.shname, aid=membership.alliance.id, accid=app.applicant.id, playername=app.applicant.empire, message=app.message) app.delete() return redirect('/alliance/accept/list/')
def cancel(request, pp): slot = int(request.GET['slot']) if pp.owner != getAccount(request): return HttpResponse('ACCOUNT') otype, olvl = pp.getPair(slot) # if we are cancelling an erection, otype == 0 ... try: otype = cancelBuild(pp, slot) # ... therefore this except: return HttpResponse('UNEXISTANT') note(request, LP_BUILD_CANCELLED, what=otype, pid=pp.province.id, levelcurrent=olvl) return HttpResponse('OK')
def order(request): mum = getCurrentMother(request) costs = getCosts(mum, getRace(request), int(request.GET['what'])) if costs[0] > getResourceIndex(request).stateUpdate(): return HttpResponse('COSTS') if mum.getPendingConstructionsCount() > 0: return HttpResponse('QUEUE') if not getRequirements(mum, getRace(request), int(request.GET['what'])).validate(mum): return HttpResponse('REQUIREMENTS') note(request, LM_CONSTRUCTION_ORDERED, mid=mum.id, what=int(request.GET['what']), levelfrom=mum.__dict__['b_'+request.GET['what']]) orderConstruct(mum, int(request.GET['what']), costs) return HttpResponse('OK')
def cancel(request): '''Cancels a technology research. When: Always doable Profits: Nothing''' mum = getCurrentMother(request) try: tek, = TechnologyResearchOrder.objects.filter(mother=mum).filter(what=int(request.GET['what'])) except ValueError: return HttpResponse('NONE') try: cancelResearch(tek) note(request, LM_RESEARCH_CANCELLED, mid=mum.id, what=int(request.GET['what']), levelcurrent=mum.owner.technology.__dict__['o_'+request.GET['what']]) except: return HttpResponse('LOL-ERROR') return HttpResponse('OK')
def cancel(request): '''Cancels a construction. Doable: Always Profits: Nothing''' mum = getCurrentMother(request) try: tek, = MotherConstructionOrder.objects.filter(mother=mum).filter(what=int(request.GET['what'])) except ValueError: return HttpResponse('NONE') try: cancelConstruct(tek) note(request, LM_CONSTRUCTION_CANCELLED, mid=mum.id, what=int(request.GET['what']), levelcurrent=mum.__dict__['b_'+request.GET['what']]) except: return HttpResponse('LOL-ERROR') return HttpResponse('OK')
def process(request): try: titan = int(request.GET['titan']) except: titan = 0 try: pluton = int(request.GET['pluton']) except: pluton = 0 try: manpower = int(request.GET['men']) except: manpower = 0 try: target = Account.objects.get(id=int(request.GET['target'])) except: return HttpResponse('FAIL') my_mum = getCurrentMother(request) acc = getAccount(request) if acc == target: return HttpResponse('SELF') rindex = getResourceIndex(request) rindex.stateUpdate() sending_res = ResourceIndex(titan=titan, pluton=pluton, men=manpower) if (sending_res == 0): return HttpResponse('NULL') if (sending_res > rindex): return HttpResponse('TOOMUCH') tg_mother = Mother.objects.get(owner=target) note(request, LM_SENT_RESOURCE, mid=my_mum.id, target=tg_mother.id, resources=sending_res) orderResourceSend(my_mum, tg_mother, sending_res.titan, sending_res.pluton, sending_res.men) return HttpResponse('OK')
def erect(request, pp): mum = getCurrentMother(request) slot = None for i in xrange(0, pp.province.slots): if pp.getPair(i)[0] == 0: slot = i break if slot == None: return HttpResponse('NOFREESLOTS') what = int(request.GET['what']) otype, olvl = pp.getPair(slot) if otype != 0: return HttpResponse('NONZEROSLOT') # Can't build in occupied space costs = getCosts(pp, getRace(request), 0, what) if pp.owner != getAccount(request): return HttpResponse('ACCOUNT') if costs[0] > getResourceIndex(request).stateUpdate(): return HttpResponse('COSTS') if pp.getPendingBuildingsCount() > 0: return HttpResponse('QUEUE') if (otype == 1) and (pp.province.titan_coef == 0): return HttpResponse('RSFAIL_TITAN') if (otype == 2) and (pp.province.pluton_coef == 0): return HttpResponse('RSFAIL_TITAN') if (otype == 3) and (pp.province.town_coef == 0): return HttpResponse('RSFAIL_TITAN') note(request, LP_BUILD_ORDERED, pid=pp.province.id, slot=slot, what=what, levelfrom=olvl) orderBuild(pp, mum, what, slot, costs) return HttpResponse('OK')
def process(request): try: aap = AllianceApplication.objects.get(applicant=getAccount(request)) except ObjectDoesNotExist: pass else: return render_to_response('alliance/apply/applying.html', {'pgo':PrimaryGUIObject(request), 'application':aap, 'alliance':aap.alliance}) if request.method == 'POST': af = NewAllianceForm(request.POST) if af.is_valid(): group_id, board_id = createAlliance(af.cleaned_data['name'], getAccount(request)) af.instance.name = af.cleaned_data['name'] af.instance.shname = af.cleaned_data['shname'] af.instance.leader = getAccount(request) af.instance.mainpage = u'Do ustawienia' af.instance.members = 1 af.instance.smf_board_id = board_id af.instance.smf_group_id = group_id af.instance.save() amb = AllianceMembership(None, af.instance.leader.id, af.instance.id, 255, u'Szef') amb.save() note(request, LA_CREATE_ALLIANCE, name=af.instance.name, shname=af.instance.shname, aid=af.instance.id) return redirect('/alliance/view/own/') try: af except: af = NewAllianceForm() return render_to_response('alliance/new/newform.html', {'form':af, 'pgo':PrimaryGUIObject(request)})
def process(request, alliance_membership, do_avatar=False): if not alliance_membership.hasPrivilege(AM_TEAMSITE): return redirect('/register/login/') avtchange_success = False if request.method == 'POST': if do_avatar: pa = AvatarForm(request.POST, request.FILES) if pa.is_valid(): if handle_img(pa.cleaned_data['avatar'], alliance_membership.alliance.id, True) == 'GIF': alliance_membership.alliance.is_avatar = 2 else: alliance_membership.alliance.is_avatar = 1 alliance_membership.alliance.save() avtchange_success = True elif request.POST['mainpage'] != '': if len(request.POST['mainpage']) > 128000: request.POST['mainpage'] = request.POST['mainpage'][:128000] alliance = alliance_membership.alliance note(request, LA_MODIFIED_TEAMSITE, name=alliance.name, shname=alliance.shname, aid=alliance.id, old=alliance.mainpage, current=request.POST['mainpage']) alliance.mainpage = request.POST['mainpage'] alliance.save() return redirect('/alliance/view/own/') try: pa except: pa = AvatarForm() return render_to_response('alliance/teamsite/teamsite.html', {'membership':alliance_membership, 'avtchange_success':avtchange_success, 'pa':pa, 'pgo':PrimaryGUIObject(request)})
def submit(request): '''The great submit procedure. Accepts nearby anything, and has to resolve it to make sense. And BTW it has to send troops''' # MEMO: If an error occurs here, it kills the script, preventing it from doing anything. It's a GOOD thing, a DEFENSE against # the user. User won't notice, because this script handles AJAX, and AJAX is processed by my JavaScript, not by browser # Quite a show off code it is, isn't it? # -------------------------------------- grab designation, and substitute it for valid in-game code designation = int(request.GET['designation']) if not (designation in (0,1,2)): return HttpResponse('HACK') # Prevent invalid designations dmap = {0:2, 1:1, 2:3} # true code for JS 0 is 2 ("Attack") # true code for JS 1 is 1 ("Attack if not allied on arrival, else Reinforce") # true code for JS 2 is 3 ("Fallback if not allied on arrival, else Reinforce") # there are also other designations(0 - I'm falling back, 4 - Reinforce, 5 - Fallback on arrival) # there are either old or debug designation = dmap[designation] # -------------------------------------- Try to ascertain what we are actually doing. And there's lotta of possibilities source = request.GET['source'] target = request.GET['target'] if (source == 'null') and (target == 'null'): raise Exception # Situation where mother is both source and target are right out if source == 'null': # We are dropping stuff from mothership mother = getCurrentMother(request) # Get our mother object target = Province.objects.get(id=int(target)) # In that case we are dropping unto a province if target.planet != mother.duePosition(): return HttpResponse('HQNT') # Mother cannot drop to a province - she's not there if mother.isRelocating(): return HttpResponse('RELOC') # Mother can't drop during a relocation # Ok, I see no reasons why we shoudn't perform the action for now. order = 'DROP' src_garrison = mother.garrison # Store mother garrison for further checking and reference elif target == 'null': # We are evacuating mother = getCurrentMother(request) # Get our mother object source = Province.objects.get(id=int(source)) # Get our province object if source.planet != mother.duePosition(): return HttpResponse('HQNT') # Mother cannot evac from a province - she's not there if mother.isRelocating(): return HttpResponse('RELOC') # Mother can't evac during a relocation if source.presence.owner != getAccount(request): # If province is not ours (if it's unoccupied, error happens) reinf = source.presence.reinforcement_set.get(owner=getAccount(request)) # If we don't have any reinforcements, error happens order = 'EVAC-REINF' # Ok, we can evacuate our reinforcements src_garrison = reinf.garrison # Store reinforcement garrison for further checking and reference else: order = 'EVAC' # Evacuate our units src_garrison = source.presence.garrison # Store provintional garrison for further checking and reference else: # We are doing a province-to-province transfer source = Province.objects.get(id=int(source)) target = Province.objects.get(id=int(target)) if source.planet != target.planet: raise Exception # Obviously, you can't make interplanetary transfers here :D if source.presence.owner != getAccount(request): return HttpResponse('HACK') # Can't comandeer a province that's not mine. Unoccupied - error if not (target in source.getNeighbours()): return HttpResponse('HACK') # Must be a neighbouring province # Ok, no reasons why we shouldn't do it order = 'ATTACK' src_garrison = source.presence.garrison # Store provintional garrison for further checking and reference # -------------------------------------- Reconstruct a garrison object from that JavaScript GET babble garrison = Garrison() for i in xrange(0, MGI+1): # Do that for every possible troop type try: gv = int(request.GET['st'+str(i)]) # Try to get troop number of troop type "i" from JavaScript GET except: # If it's not there... gv = 0 # Ignore the error. There might be more units ahead to read. garrison[i] = gv # Store the value unto garrison i += 1 # Increase i # ------------------------------------- Check whether we can send that many troops if garrison.isZero(): return HttpResponse('ZERO') # You want to send 0 units? How could it be... if not (garrison in src_garrison): return HttpResponse('HACK') # ------------------------------------- Being outfitted with knowledge of what to do, and with that to do that, let's do that ;) # In each case, we will list variables that are already ready to use. if order == 'EVAC': # Process evacuation request orderMotherPickup(source.presence, garrison, mother, race=getRace(request)) # Order the evacuation note(request, LP_MOTHER_PICKUP_LAND, pid=source.id, garrison=garrison, mid=mother.id) # Store info about evacuation to last-done-stuff(LARF, ie. Last Actions Reporting Format) elif order == 'EVAC-REINF': # Process reinforcement evacuation request orderReinforcementsPickup(source.presence, garrison, mother, reinf, race=getRace(request)) note(request, LP_MOTHER_PICKUP_LAND, pid=source.id, garrison=garrison, mid=mother.id) # Save info about pickup into LARF elif order == 'DROP': # Process drop request orderPlanetaryStrike(garrison, mother, target, designation, 0, race=getRace(request)) # order the drop # Last zero parameter is a placeholder to additional commands # if these were to be implemented at some point in-game note(request, LM_DEPLOY_LAND_GROUND, mid=mother.id, garrison=garrison, provinceid=target.id, designation=designation, orders=0) # Save info into LARF elif order == 'ATTACK': # Process province-to-province transfers orderProvintionalStrike(garrison, source, target, designation, 0, race=getRace(request)) # Order the strike note(request, LP_DEPLOY_LAND_GROUND, pid=source.id, garrison=garrison, target=target, designation=designation, orders=0) # Store info about the deployment into LARF else: # Something terrible, terrible has happened. We are processing unknown order, or our code took an exceptionally wrong codepath. # It's so terrible it's disgusting. And it's totally my fault. If something like that happens, I should fix it ASAP. raise Exception return HttpResponse('OK') # Signal that stuff went just OK
def doLandarmyProvintionalStrikeOrder(entry, lpso=None): ''' If order was to reinforce, signal Exception ''' if lpso == None: lpso = LandarmyProvintionalStrikeOrder.objects.get(got=entry) wtd = whatToDo(lpso.attacker, lpso.dstprovince, lpso.designation) if wtd == 'REINFORCE': if lpso.attacker == lpso.dstprovince.presence.owner: # Reinforce own province lpso.dstprovince.presence.garrison # make sure it's ready lpso.dstprovince.presence.garrison += lpso.garrison lpso.garrison.delete() lpso.dstprovince.presence.garrison.save() lpso.delete() return try: reinforcement = lpso.dstprovince.presence.reinforcement_set.get(owner=lpso.attacker) except: # Was not previously reinforced, need to make new classes Reinforcement(None, lpso.attacker.id, lpso.dstprovince.presence.id, lpso.garrison.id, lpso.orders).save() lpso.delete() return else: # Reinforce already reinforced troops reinforcement.garrison += lpso.garrison reinforcement.garrison.save() lpso.garrison.delete() lpso.delete() return elif wtd == 'FALLBACK': lpso.directiveFallback(0) raise DontRemoveGOT elif wtd == 'ASSAULT': try: lpso.dstprovince.presence # If uninhabited? except: pres = ProvintionalPresence(id=None, garrison=lpso.garrison, owner=lpso.attacker, province=lpso.dstprovince, garrison_orders=0) pres.save() lpso.delete() return # War! # lpso.attacker WITH HIS lpso.garrison IS ATTACKING lpso.dstprovince report = WarfareReport() report.initializeEnvironment(lpso.srcprovince, lpso.dstprovince, datetime.now()) report.initializeParties(lpso.attacker, lpso.dstprovince.presence.owner) attacker_army, defender_army = prepare(lpso) attacker_won = perform(attacker_army, defender_army, report) cleanup(attacker_army, defender_army, report, attacker_won) rep = makeReport(report, u'Raport wojenny z '+lpso.dstprovince.name) sendTo(rep, lpso.attacker, False) sendTo(rep, lpso.dstprovince.presence.owner, False) for reinf in lpso.dstprovince.presence.reinforcement_set.all(): sendTo(rep, reinf.owner, False) note(None, LX_PROVINCE_COMBAT_LAND, attacker_id=lpso.attacker.id, defender_id=lpso.dstprovince.presence.owner.id, source_pid=lpso.srcprovince.id, target_pid=lpso.dstprovince.id, attacker_won=attacker_won) if attacker_won == True: defender = lpso.dstprovince.presence.owner lpso.dstprovince.presence.unsettle_dueToAssault() lpso.dstprovince.presence.garrison.clone(lpso.garrison) lpso.dstprovince.presence.garrison.save() lpso.dstprovince.presence.owner = lpso.attacker lpso.dstprovince.presence.save() lpso.garrison.delete() # Slay all reinforcement garrisons for reinf in lpso.dstprovince.presence.reinforcement_set.all(): reinf.garrison.delete() reinf.delete() from bellum.common.fixtures.resources import recalc recalc(defender) recalc(lpso.attacker) else: # if (attacker_won == False) or (attacker_won == None): # Save all reinforcement garrisons, delete if necessary for reinf in lpso.dstprovince.presence.reinforcement_set.all(): if reinf.garrison.isZero(): reinf.garrison.delete() reinf.delete() else: reinf.garrison.save() lpso.dstprovince.presence.garrison.save() if attacker_won == False: lpso.garrison.delete() if attacker_won == None: # stalemate # pack attackers bags and send him home lpso.garrison.save() lpso.directiveFallback() raise DontRemoveGOT lpso.delete()
def doLandarmyPlanetaryStrikeOrder(entry): ''' If order was to reinforce, signal Exception ''' lpso = LandarmyPlanetaryStrikeOrder.objects.get(got=entry) wtd = whatToDo(lpso.mother.owner, lpso.province, lpso.designation) if wtd == 'REINFORCE': if lpso.mother.owner == lpso.province.presence.owner: # Reinforce own province lpso.province.presence.garrison += lpso.garrison lpso.province.presence.garrison.save() lpso.garrison.delete() lpso.delete() return # Reinforce somebody's else province try: reinforcement = lpso.province.presence.reinforcement_set.get(owner=lpso.mother.owner) except: # I have no reinforcements in this province Reinforcement(None, lpso.mother.owner.id, lpso.province.presence.id, lpso.garrison.id, lpso.orders).save() lpso.delete() return else: # I do have reinforcements on this province reinforcement.garrison += lpso.garrison reinforcement.garrison.save() lpso.garrison.delete() lpso.delete() return elif wtd == 'FALLBACK': lmpo = LandarmyMotherPickupOrder(None, lpso.got.id, lpso.mother.id, lpso.province.id, lpso.garrison.id) lmpo.save() lpso.got.ordertype = 8 lpso.got.to_be_completed += timedelta(0, int(pmmovelen(lpso.province, lpso.mother, lpso.garrison))) lpso.got.save() lpso.delete() raise DontRemoveGOT elif wtd == 'ASSAULT': try: lpso.province.presence # If uninhabited? except: pres = ProvintionalPresence(id=None, garrison=lpso.garrison, owner=lpso.mother.owner, province=lpso.province, garrison_orders=lpso.orders) pres.save() lpso.delete() return report = WarfareReport() report.initializeEnvironment(lpso.mother, lpso.province, datetime.now()) report.initializeParties(lpso.mother.owner, lpso.province.presence.owner) attacker_army, defender_army = prepare(lpso) attacker_won = perform(attacker_army, defender_army, report, is_drop=True) cleanup(attacker_army, defender_army, report, attacker_won) rep = makeReport(report, u'Raport wojenny z '+lpso.province.name) sendTo(rep, lpso.mother.owner, False) sendTo(rep, lpso.province.presence.owner, False) for reinf in lpso.province.presence.reinforcement_set.all(): sendTo(rep, reinf.owner, False) note(None, LX_DROP_COMBAT_LAND, attacker_id=lpso.mother.owner, defender_id=lpso.province.presence.owner, province_id=lpso.province, attacker_won=attacker_won) if attacker_won: defender = lpso.province.presence.owner # Elliminate all reinforcements reinfs = Reinforcement.objects.filter(presence=lpso.province.presence) for reinf in reinfs: reinf.garrison.delete() reinf.delete() lpso.province.presence.unsettle_dueToAssault() lpso.province.presence.garrison.clone(lpso.garrison)# Copy to presence's garrison info about garrison lpso.province.presence.garrison.save() lpso.province.presence.owner = lpso.mother.owner # Change owner lpso.province.presence.save() lpso.garrison.delete() from bellum.common.fixtures.resources import recalc recalc(defender) recalc(lpso.mother.owner) if attacker_won in (False, None): # save garrisons # Save all reinforcement garrisons, delete if necessary for reinf in lpso.province.presence.reinforcement_set.all(): if reinf.garrison.isZero(): reinf.garrison.delete() reinf.delete() else: reinf.garrison.save() lpso.province.presence.garrison.save() if attacker_won == False: lpso.garrison.delete() if attacker_won == None: lpso.garrison.save() lpso.fallback() raise DontRemoveGOT lpso.delete()